#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Last Update:

'''process tables in word
'''

__revision__ = '0.1'
__author__ = 'lxd'
import win32com.client
from win32com.client import Dispatch, constants, pywintypes

class Word(object):
    def __init__(self, visible = True):
        # can use win32com.client.constants now
        self.word = win32com.client.gencache.EnsureDispatch('Word.Application')
        self.word.Visible = visible
        self.word.DisplayAlerts = False

    def open(self, filename):
        self.word.Documents.Open(filename)
        # close spelling and grammar check
        self.word.ActiveDocument.GrammarChecked = True
        self.word.ActiveDocument.SpellingChecked = True

        #improve performance
        self.word.ActiveDocument.View = constants.wdNormalView
        self.word.ActiveDocument.Application.Options.Pagination = False
        self.word.ActiveDocument.Application.ScreenUpdating = False

    def new(self):
        self.word.Documents.Add()

    def save(self):
        self.word.ActiveDocument.Save()

    def close(self):
        self.word.Documents.Close()

    def copy(self):
        self.word.Selection.Copy()

    def paste(self):
        self.word.Selection.Paste()

    def selectAll(self):
        self.word.Selection.WholeStory()

    def getSelection(self):
        return self.word.Selection

    def setMousePos(self, *args):
        if len(args) == 1:
            self.word.Selection.SetRange(args[0], args[0])
        elif len(args) == 2:
            self.word.Selection.SetRange(args[0], args[1])

    def getMousePos(self):
        return self.word.Selection.Range.End

    def getAllTables(self):
        return self.word.ActiveDocument.Tables

    def getTable(self):
        if self.word.Selection.Tables.Count>0:
            self.table = self.word.Selection.Tables[0]
        else:
            self.table = self.word.ActiveDocument.Tables[0]

    def nextLine(self, num = 1):
        for i in range(num):
            self.word.Selection.TypeParagraph()

    def insertPageBreak(self):
        self.word.Selection.InsertBreak(constants.wdPageBreak)

    def insertWordAndSetStyle(self, word, styleName):
        startPos, endPos = self.insertWord(word)
        self.setWordStyle(startPos, endPos, styleName)

    def insertWord(self, word):
        #insert word and return start and end positions
        start = self.getMousePos()
        self.word.Selection.TypeText(word)
        end = self.getMousePos()
        return start, end

    def setWordStyle(self, startPos, endPos, styleName):
        self.setMousePos(startPos, endPos)
        self.word.Selection.Style = self.word.ActiveDocument.Styles(styleName)
        self.setMousePos(endPos)

    ##########table##########
    def getCellText(self, x, y):
        s = self.table.Cell(x+1, y+1).Range.Text
        # 去掉多余的回车和换行
        return s[:-2]

    def isBlank(self, cell):
        return cell.Range.Characters.Count == 1

    def isBlankRow(self, index):
        columns = self.table.Columns.Count
        for i in range(1, columns + 1):
            try:
                if not self.isBlank(self.table.Cell(index+1, i)):
                    return False
            except pywintypes.com_error, ex:
                ex = ex.args
                if len(ex) == 4 and len(ex[2]) == 6:
                    if ex[2][2] == u'集合所要求的成员不存在。':
                        return False
        return True
    def autoFit(self):
        self.table.AutoFitBehavior(constants.wdAutoFitWindow)

    def headingFormat(self):
        self.selectRow(0)
        self.word.Selection.Rows.HeadingFormat = True
    def setMouseBeforeTable(self):
        pos = self.table.Range.Start
        self.setMousePos(pos-1)

    def selectRow(self, index):
        self.table.Cell(index+1, 1).Select()
        self.word.Selection.SelectRow()

    def selectColumn(self, index):
        word.table.Cell(1, index+1).Select()
        word.word.Selection.SelectColumn()

    def delRow(self, index):
        self.selectRow(index)
        self.word.Selection.Range.Cells.Delete()

    def setFont(self, item, size = 10.5, bold = False):
        """
        @item   word.Selection.Tables[0]
        """
        item.Range.Font.Name = u'宋体'
        item.Range.Font.Name = 'Times New Roman'
        item.Range.Font.Color = constants.wdColorAutomatic
        item.Range.Font.Size = size
        if bold:
            item.Range.Font.Bold = True

    def setCenter(self, item):
        """
        @item   word.Selection
        """
        item.Range.ParagraphFormat.Alignment = constants.wdAlignParagraphCenter
        item.Range.Cells.VerticalAlignment = constants.wdCellAlignVerticalCenter

    def setVCenter(self, item):
        """
        @item   word.Selection
        """
        item.Range.Cells.VerticalAlignment = constants.wdCellAlignVerticalCenter

    def setHCenter(self, item):
        """
        @item   word.Selection
        """
        item.Range.ParagraphFormat.Alignment = constants.wdAlignParagraphCenter

    def setBorder(self, item, styles = [1, 1, 1, 1]):
        """
        @item   word.Selection.Cells
                word.Selection.Tables[0].Cell(1, 1)
        """
        def _setSingleBorder(border):
            border.LineStyle = constants.wdLineStyleSingle
            border.LineWidth = constants.wdLineWidth050pt
            border.Color = constants.wdColorAutomatic

        def _setNoneBorder(border):
            border.LineStyle = constants.wdLineStyleNone

        borders = [constants.wdBorderTop, constants.wdBorderTop, constants.wdBorderTop, constants.wdBorderTop]
        for i, v in enumerate(borders):
            if styles[i]:
                _setSingleBorder(item.Borders(v))
            else:
                _setNoneBorder(item.Borders(v))

    def insertMergeRowWithTitle(self, index, title):
        self.selectRow(index)
        self.word.Selection.InsertRowsAbove(1)
        self.word.Selection.Cells.Merge()
        self.insertWord(title)

    def setSubTitleStyle(self, index):
        self.selectRow(index)
        self.setFont(self.word.Selection, bold = True)
        self.setBorder(self.word.Selection.Cells)

        self.word.Selection.ParagraphFormat.Alignment = constants.wdAlignParagraphLeft
        self.word.Selection.Cells.Shading.BackgroundPatternColor = -603917569
        self.word.Selection.Rows.Height = 0.75

    ##########apply##########
    def copyToAnother(self):
        self.selectAll()
        self.copy()
        self.close()

        self.new()
        self.nextLine()
        self.paste()

    def safeProcessCell(self, fun, i, j):
        """对cell(i, j)执行fun函数，成功返回True，失败返回False
        """
        try:
            fun(self.table.Cell(i+1, j+1))
            return True
        except pywintypes.com_error, ex:
            args = ex.args
            if args and len(args) == 4:
                if args[2] and len(args[2]) == 6:
                    if args[2][2] == u'集合所要求的成员不存在。':
                        return False
            raise

if __name__ == '__main__':
    word = Word()
    word.getTable()
    word.insertMergeRowWithTitle(3, u'中国3')
    

